package com.tianquan.miracle.context;

import com.tianquan.miracle.annotation.EnableAutoConfiguration;
import com.tianquan.miracle.annotation.MiracleFastApplication;
import com.tianquan.miracle.beans.ScannerClassLoad;

import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @Author: tianquan
 * @date: 2024-09-29  10:33
 * @Description: 默认上下文容器 DefaultApplicationContext 类是 GeneralApplicationContext 的一个实现类
 * 它负责处理类的加载、自动配置的检查以及提供应用启动的上下文环境
 */
public class DefaultApplicationContext extends GeneralApplicationContext {

    /**
     * 用于扫描指定包路径下的所有类的加载器
     */
    private final ScannerClassLoad scannerClass = new ScannerClassLoad();

    /**
     * 应用的主类
     */
    private final Class<?> clazz;

    /**
     * 应用启动的参数
     */
    private final String[] args;

    /**
     * 标记自动配置是否已启用
     */
    private Boolean isEnabled = false;

    /**
     * 检查自动配置是否已启用
     *
     * @return 返回自动配置的启用状态
     */
    @Override
    public Boolean isEnabled() {
        return isEnabled;
    }

    /**
     * 在指定的包及其子包中查找所有类
     *
     * @return 返回找到的所有类的列表
     */
    @Override
    public List<Class<?>> findClassesInPackageAndSubpackages() {
        return loadClass(clazz);
    }

    /**
     * 扩展预设的 Bean 后处理器
     *
     * @return 返回一个空的 HashSet，表示当前没有扩展任何后处理器
     */
    @Override
    public Set<String> extendPreBeanPostProcessor() {
        return new HashSet<>();
    }

    /**
     * 加载指定类的所有子类
     *
     * @param clazz 要加载类的父类
     * @return 返回找到的所有子类的列表
     */
    public List<Class<?>> loadClass(Class<?> clazz) {
        return loadClass(clazz.getPackageName());
    }

    /**
     * 加载指定包路径下的所有类
     *
     * @param packageName 包的路径
     * @return 返回找到的所有类的列表
     */
    @Override
    public List<Class<?>> loadClass(String packageName) {
        return scannerClass.loadClass(packageName);
    }

    /**
     * 构造函数，初始化 DefaultApplicationContext 实例
     *
     * @param clazz 应用的主类
     * @param args  应用启动的参数
     */
    public DefaultApplicationContext(Class<?> clazz, String[] args) {
        lookUpIsEnableAutoConfiguration(clazz);
        this.clazz = clazz;
        this.args = args;
    }

    /**
     * 检查是否启用了自动配置
     *
     * @param clazz 应用的主类，用于检查其上的注解
     */
    public void lookUpIsEnableAutoConfiguration(Class<?> clazz) {
        // 是否开启自动配置类
        Annotation[] annotations = clazz.getAnnotations();
        for (Annotation annotation : annotations) {
            // 检查 EnableAutoConfiguration 注解
            if (annotation instanceof EnableAutoConfiguration enableAutoConfiguration) {
                isEnabled = enableAutoConfiguration.value();
                return;
            }
            // 检查 MiracleFastApplication 注解
            if (annotation instanceof MiracleFastApplication) {
                isEnabled = true;
            }
        }
    }

}

